package com.hockeo.shared.rpc.command;

import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.hockeo.shared.VHUtil;
import com.hockeo.shared.rpc.command.error.NotAnAdminException;
import com.hockeo.shared.rpc.command.error.NotAuthenticatedException;
import com.hockeo.shared.rpc.command.error.SessionInvalidException;

/**
 * Standard implementation of GWT's {@link AsyncCallback} interface. Provided to complete
 * VH's implementation of the command pattern presented at Google I/O 2009 (GWT best
 * practices).
 *
 * @param <T> represents the type of response that is expected by this callback
 * @version $Id$
 * @author jjanke
 */
public abstract class CommandCallback<T extends IResponse> implements AsyncCallback<T>
{
  @Override
  public void onFailure( Throwable t )
  {
    if ( t instanceof SessionInvalidException )
    {
      // the user's session is not valid - let's clear the session cookie and redirect the
      // user to the login page
      //
      clearSessionCookie();
      redirectToLogin( (SessionInvalidException) t );
    }
    else if ( t instanceof NotAuthenticatedException )
    {
      // the user is not authenticated, redirect him to the login page
      //
      redirectToLogin( (NotAuthenticatedException) t );
    }
    else if ( t instanceof NotAnAdminException )
    {
      // display a message that the user's rights are not sufficient for the command he
      // wants to execute
      //
      Window.alert( VHUtil.constants().notAnAdminFailure() );
    }
    else
    {
      // TODO: better error handling
      Window.alert( t.toString() );
    }
  }

  @Override
  public void onSuccess( T response )
  {
    got( response );
  }

  /**
   * Is called once a response has been received. This should be overridden in order to do
   * something with the obtained result.
   *
   * @param response the received command response
   */
  public abstract void got( T response );

  /**
   * Clears the session cookie if it is set.
   */
  private void clearSessionCookie()
  {
    if ( Cookies.getCookie( VHUtil.SESSION_COOKIE ) != null )
      Cookies.removeCookie( VHUtil.SESSION_COOKIE );
  }

  /**
   * Redirects the connected user to the login page.
   *
   * @param ex the exception providing access to the login URL
   */
  private void redirectToLogin( NotAuthenticatedException ex )
  {
    Window.open( ex.getLoginUrl() + VHUtil.getUrlSuffix(), "_self", "" );
  }
}
